package UtilsApplication;

import ModelApplication.ComplexArray;
import ModelApplication.Filter;

public class FilterSpectrum {

    public static ComplexArray filter(Filter filter, ComplexArray spectrum) {
        
        double [] real = spectrum.getReal();
        double [] img = spectrum.getImg();
        
        double [] realNew = new double [real.length];
        double [] imgNew = new double [real.length];
        
        int low = (int)(filter.getLow() * ((float)real.length / 44100.0));
        int high = (int)(filter.getHeight() * ((float)real.length / 44100.0));

        for(int i = low; i < high; i++) {
            realNew[i] = real[i];
            imgNew[i] = img[i];
        }
        for(int i = real.length - high; i< real.length - low; i++) {
            realNew[i] = real[i];
            imgNew[i] = img[i];
        }
        
        ComplexArray out = new ComplexArray( realNew, imgNew );
        
        return out;
    }
    
    public static double [] filter(Filter filter, double [] audio) {
        double[] y = FilterSpectrum.lowPassFillter(audio, filter.getHeight(), 1.0);
        y = highPassFillter(y, filter.getLow(), 1.0);
        return y;
    }
    
    
    /**
    *
    * @param x sygnał
    * @param f częstotliwość odcięcia
    * @param q współczynnik rezonansu
    * @return
    */
   public static double[] lowPassFillter(double[] x, int f, double q) {
       double[] y = new double[x.length];
       double s = Math.sin(Math.PI * 2 * f / 44100);
       double c = Math.cos(Math.PI * 2 * f / 44100);
       double alfa = s / (2 * q);
       double r = 1 / (1 + alfa);

       double a0 = 0.5 * (1 - c) * r;
       double a1 = (1 - c) * r;
       double a2 = a0;
       double b1 = -2 * c * r;
       double b2 = (1 - alfa) * r;

       //Pierwsze dwa są te same
       y[0] = x[0];
       y[1] = x[1];
       for (int i = 2; i < x.length; i++) {
           y[i] = (double) (a0 * x[i] + a1 * x[i - 1] + a2 * x[i - 2] - b1 * y[i - 1] - b2 * y[i - 2]);
       }
       return y;
   }

   /**
    *
    * @param x sygnał
    * @param f częstotliwość odcięcia
    * @param q współczynnik rezonansu
    * @return
    */
   public static double[] highPassFillter(double[] x, double f, double q) {
       double[] y = new double[x.length];
       double s = Math.sin(Math.PI * 2 * f / 44100);
       double c = Math.cos(Math.PI * 2 * f / 44100);
       double alfa = s / (2 * q);
       double r = 1 / (1 + alfa);

       double a0 = 0.5 * (1 + c) * r;
       double a1 = -(1 + c) * r;
       double a2 = a0;
       double b1 = -2 * c * r;
       double b2 = (1 - alfa) * r;

       //Pierwsze dwa są te same
       y[0] = x[0];
       y[1] = x[1];
       for (int i = 2; i < x.length; i++) {
           y[i] = (double) (a0 * x[i] + a1 * x[i - 1] + a2 * x[i - 2] - b1 * y[i - 1] - b2 * y[i - 2]);
       }
       return y;
   }

    
}
